import React, { useState } from 'react'
import { Card, Descriptions, Row, Col, Button, Input, Table, Tag, Space, message } from 'antd'
import { useRequest, useMount } from 'ahooks'
import moment from 'moment'

import { getCommunicationInfo, listContracts, listApplications, operateApplication } from '@/pages/Dashboard/components/CrossChain/service'
import NewCrossChainApplication from '@/pages/Dashboard/components/CrossChain/pages/CrossChainApplication/components/New'
import { COMMUNICATION_APPLICATION_STATUS } from '@/pages/Dashboard/components/CrossChain/enums'
import { checkPermission } from '@/components/AuthComponent/utils'
import { USER_INFO } from '@/Utils/CONST'

const { Search } = Input

import './index.less'

const searchOption = {
  page: 1,
  per_page: 10,
  id__contains: '',
}

const ContractChainInfo = ({ match }) => {
  const chainId = match.params.id
  const [chainInfo, setChainInfo] = useState({})
  const [blockInfo, setBlockInfo] = useState({})
  const [listenedContractFunc, setListenedContractFunc] = useState({});
  const [voteTimeoutBlocks, setVoteTimeoutBlocks] = useState(30)
  const [modalVisible, setModalVisible] = useState(false)
  const [applications, setApplications] = useState([])
  const [totalApplications, setTotalApplications] = useState(0)
  const { loading: loadingInfo, run: getInfo } = useRequest(getCommunicationInfo, { manual: true })
  const { loading: loadingApplications, run: getApplications } = useRequest(listApplications, { manual: true })
  const { loading: operatingApplication, run: opApplication } = useRequest(operateApplication, { manual: true })
  const [currentApplication, setCurrentApplication] = useState(null)
  // const [channels, setChannels] = useState([])
  const [contracts, setContracts] = useState([])
  // const { run: getChannels } = useRequest(listDeployedChannels, { manual: true })
  const { run: loadContracts } = useRequest(listContracts, { manual: true })
  const queryApplications = async(params = {}) => {
    try {
      const res = await getApplications({
        ...searchOption,
        ...params,
        sponsor: chainId,
      })
      const { data: { data, total, blockInfo, voteTimeoutBlocks }} = res
      setApplications(data)
      setTotalApplications(total)
      setVoteTimeoutBlocks(voteTimeoutBlocks)
      setBlockInfo(blockInfo)
    } catch (e) {
      console.error(e)
    }
  }
  const queryTargetConnectedApplications = async() => {
    try {
      const res = await listApplications({
        // 连接成功的申请
        status: 3,
        per_page: -1,
        source: chainId,
      })
      const { data: { data = [] }} = res
      const listenedFuncDict = {}
      data.map((item) => {
        const { source_listen_funcId, source_listen_funcName } = item
        const oldData = listenedFuncDict[source_listen_funcId] || []
        listenedFuncDict[source_listen_funcId] = [...oldData, source_listen_funcName]
      })
      setListenedContractFunc(listenedFuncDict)
    } catch (e) {
      console.error(e)
    }
  }
  const handleApplication = async(record, approve = true) => {
    setCurrentApplication(record.id)
    const res = await opApplication(chainId, record.id, { approve })
    const { data: { success }} = res
    if (success) {
      message.success('操作成功')
      queryApplications()
    }
    setCurrentApplication(null)
  }

  const userInfo = JSON.parse(localStorage.getItem(USER_INFO) || '{}')
  const isCreator = userInfo.id === chainInfo.creator

  const columns = [
    {
      title: '申请ID',
      dataIndex: 'id',
      key: 'id',
    },
    {
      title: '合约名称',
      dataIndex: 'contract_name',
      key: 'contract_name',
    },
    {
      title: '发起者',
      dataIndex: 'sponsor_name',
      key: 'sponsor_name',
    },
    {
      title: '源链 (名称/方法名)',
      dataIndex: 'source_name',
      key: 'source_name',
      render: (_, row) => <span>{row.source_name} / {row.source_chain_funcName}</span>,
    },
    {
      title: '目标链 (名称/方法名)',
      dataIndex: 'target_name',
      key: 'target_name',
      render: (_, row) => <span>{row.target_name} / {row.target_chain_funcName}</span>,
    },
    {
      title: '创建时间',
      dataIndex: 'created_at',
      key: 'created_at',
      render: (v) => v ? moment(v).format('YYYY-MM-DD HH:mm:ss') : '--',
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      render: (text) => <Tag color={COMMUNICATION_APPLICATION_STATUS[text].status}>{COMMUNICATION_APPLICATION_STATUS[text].label}</Tag>,
    },
    {
      title: '操作',
      dataIndex: 'sponsor',
      key: 'operation',
      render: (text, row) => {
        const isTargetCreator = userInfo.id === row.target_creator
        const { blocks_of_first_vote: blocksOfFirstVote = 0 } = row
        const currBlockHeight = parseInt(blockInfo.blockHeight || '0')
        const disabled = text === chainId || !isTargetCreator ||
          ['connected', 'rejected', 'error'].indexOf(COMMUNICATION_APPLICATION_STATUS[row.status].value) >= 0 ||
          blocksOfFirstVote + voteTimeoutBlocks > currBlockHeight
        return (
          checkPermission('cross-chain-communication-handle', 'POST') &&
          <Space>
            <Button
              loading={currentApplication === row.id && operatingApplication}
              disabled={disabled}
              type="link"
              onClick={() => handleApplication(row, true)}
            >
              同意
            </Button>
            <Button
              loading={currentApplication === row.id && operatingApplication}
              disabled={disabled}
              type="link"
              onClick={() => handleApplication(row, false)}
              danger
            >
              拒绝
            </Button>
          </Space>
        )
      },
    },
  ]
  const fetchInfo = async(id) => {
    try {
      const res = await getInfo(id)
      const { data: { data }} = res
      setChainInfo(data)
    } catch (e) {
      console.error(e)
    }
  }

  const queryContracts = async() => {
    try {
      const res = await loadContracts({ per_page: -1 })
      const { data: { data: contracts }} = res
      setContracts(contracts)
    } catch (e) {
      console.error(e)
    }
  }

  useMount(() => {
    fetchInfo(chainId)
    queryContracts()
    queryApplications()
    queryTargetConnectedApplications()
  })
  const onApplicationSuccess = () => {
    queryApplications({
      sponsor: chainId,
    })
    setModalVisible(false)
  }

  const onSearch = (value) => {
    searchOption.contract_name__contains = value
    searchOption.page = 1
    queryApplications()
  }

  const onPageChange = (current, pageSize) => {
    searchOption.page = current
    searchOption.per_page = pageSize
    queryApplications()
  }
  return (
    <div>
      <Card loading={loadingInfo}>
        <Descriptions column={3}>
          <Descriptions.Item label={<span className="label">通讯链类型</span>}>
            Hyperledger fabric
          </Descriptions.Item>
          <Descriptions.Item label={<span className="label">通讯链名称</span>}>
            {chainInfo.name}
          </Descriptions.Item>
          {
            !!chainInfo.baas_management &&
            <Descriptions.Item label={<span className="label">所属联盟</span>}>
              {chainInfo.consortium_domain}
            </Descriptions.Item>
          }
          <Descriptions.Item label={<span className="label">创建时间</span>}>
            {chainInfo.created_at ? moment(chainInfo.created_at).format('YYYY-MM-DD HH:mm:ss') : '--'}
          </Descriptions.Item>
          {
            !!chainInfo.baas_management &&
            <Descriptions.Item label={<span className="label">所属通道</span>}>
              {chainInfo.channel_name}
            </Descriptions.Item>
          }
          <Descriptions.Item label={<span className="label">通讯链权限</span>}>
            <Space>
              {chainInfo.can_send && <Tag>发送</Tag>}
              {chainInfo.acceptable && <Tag>接收</Tag>}
            </Space>
          </Descriptions.Item>
        </Descriptions>
      </Card>
      <Card style={{ marginTop: 24 }}>
        <Row style={{ marginBottom: 18 }}>
          <Col span={8}>
            {
              checkPermission('cross-chain-communication-apply', 'POST') && isCreator &&
              <Button type="primary" onClick={() => setModalVisible(true)}>
              申请跨链通讯
              </Button>
            }
          </Col>
          <Col span={16} style={{ textAlign: 'right' }}>
            <Search allowClear onSearch={onSearch} className="search" placeholder="输入合约名称" style={{ width: 260 }} />
          </Col>
        </Row>
        <Table
          loading={loadingApplications}
          dataSource={applications}
          columns={columns}
          rowKey="id"
          pagination={{
            current: searchOption.page,
            pageSize: searchOption.per_page,
            position: ['bottomCenter'],
            showTotal: (total, range) => `共 ${total} 条记录 第 ${range[0]}-${range[1]} 项`,
            showSizeChanger: true,
            showQuickJumper: true,
            total: totalApplications,
            onChange: onPageChange,
          }}
        />
      </Card>
      <NewCrossChainApplication visible={modalVisible} onSuccess={onApplicationSuccess} onCancel={() => setModalVisible(false)} chain={chainInfo} contracts={contracts} listenedContractFunc={listenedContractFunc} />
    </div>
  )
}

export default ContractChainInfo
